#include "../include/hikvisionDriver.h"
#include <stdio.h>
#include <endian.h>
#include <stdio.h>
#include <curl/curl.h>
#include <curl/easy.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

/* 需要设置的xml */
static char* gOsdXmlResource =  "<?xml version=\"1.0\" encoding=\"UTF-8\"?><TextOverlayList xmlns=\"http://www.isapi.org/ver20/XMLSchema\" version=\"2.0\"><TextOverlay><id>1</id><enabled>true</enabled><positionX>576</positionX><positionY>48</positionY><displayText>%s</displayText><OverlayRegion><width>200</width><height>50</height></OverlayRegion></TextOverlay></TextOverlayList>";
static char* gTimeXmlResource = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Time xmlns=\"http://www.isapi.org/ver20/XMLSchema\" version=\"2.0\"><timeMode>manual</timeMode><localTime>%s</localTime><timeZone>CST-8:00:00</timeZone><satelliteInterval>60</satelliteInterval><isSummerTime>true</isSummerTime><platformType>EZVIZ</platformType><platformNo>1</platformNo></Time>";

/* 海康威视摄像头 */
static cameraObj hikvisionCamera;

static unsigned int writeOSDData(void *contents, size_t size, size_t nmemb, void *userp)
{
    printf("start onWritrdata\r\n");
    //printf("\r\n %s\r\n",(char*)contents);
    const char* buf = (char*)contents;

    //xmlKeepBlanksDefault(0);//忽略回车空格
    xmlDocPtr my_doc = xmlParseMemory(buf, strlen(buf)); //将字符串转换成xmldoc
    xmlNodePtr my_root_node = xmlDocGetRootElement(my_doc);//获取根节点

    xmlNodePtr my_child_node = my_root_node->children;//获取子节点

    while (my_child_node != NULL) 
    {
        if(my_child_node->type == XML_ELEMENT_NODE)
        {
            if(!strcmp(my_child_node->name, "requestURL"))
            {
                printf("request = %s.\r\n",xmlNodeGetContent(my_child_node));
            }
            else if(!strcmp(my_child_node->name,"statusString"))
            {
                printf("statusString = %s.\r\n",xmlNodeGetContent(my_child_node));
            }
        }
        my_child_node = my_child_node->next;
    }
    
    xmlFreeDoc(my_doc);//释放
    
    return size * nmemb;
}

static unsigned int writeTimeData(void *contents, size_t size, size_t nmemb, void *userp)
{
    printf("start onWritrdata\r\n");
    //printf("\r\n %s\r\n",(char*)contents);
    const char* buf = (char*)contents;

    //xmlKeepBlanksDefault(0);//忽略回车空格
    xmlDocPtr my_doc = xmlParseMemory(buf, strlen(buf)); //将字符串转换成xmldoc
    xmlNodePtr my_root_node = xmlDocGetRootElement(my_doc);//获取根节点

    xmlNodePtr my_child_node = my_root_node->children;//获取子节点

    while (my_child_node != NULL) 
    {
        if(my_child_node->type == XML_ELEMENT_NODE)
        {
            if(!strcmp(my_child_node->name, "requestURL"))
            {
                printf("request = %s.\r\n",xmlNodeGetContent(my_child_node));
            }
            else if(!strcmp(my_child_node->name,"statusString"))
            {
                printf("statusString = %s.\r\n",xmlNodeGetContent(my_child_node));
            }
        }
        my_child_node = my_child_node->next;
    }
    
    xmlFreeDoc(my_doc);//释放
    
    return size * nmemb;
}

static unsigned int ReadTimeData(void *contents, size_t size, size_t nmemb, void *userp)
{
    printf("start onReaddata\r\n");
    printf("\r\n %s\r\n",(char*)contents);
    const char* buf = (char*)contents;
    pdeviceTime timetemp = (deviceTime *)(userp);

    //xmlKeepBlanksDefault(0);//忽略回车空格
    xmlDocPtr my_doc = xmlParseMemory(buf, strlen(buf)); //将字符串转换成xmldoc
    xmlNodePtr my_root_node = xmlDocGetRootElement(my_doc);//获取根节点
    xmlNodePtr my_child_node = my_root_node->children;//获取子节点
    while (my_child_node != NULL) 
    {
        if(my_child_node->type == XML_ELEMENT_NODE)
        {
            if(!strcmp(my_child_node->name, "timeMode"))
            {
                timetemp->timemode = xmlNodeGetContent(my_child_node);
            }
            else if(!strcmp(my_child_node->name,"localTime"))
            {
                timetemp->localtime = xmlNodeGetContent(my_child_node);
            }
        }
        my_child_node = my_child_node->next;
    }
    xmlFree(my_doc);
    return size * nmemb;
}

static unsigned int ReadInforData(void *contents, size_t size, size_t nmemb, void *userp)
{
    printf("start onReaddata\r\n");
    printf("\r\n %s\r\n",(char*)contents);
    const char* buf = (char*)contents;
    pDeviceInfor deviceInforTemp = (deviceInfor *)(userp);

    //xmlKeepBlanksDefault(0);//忽略回车空格
    xmlDocPtr my_doc = xmlParseMemory(buf, strlen(buf)); //将字符串转换成xmldoc
    xmlNodePtr my_root_node = xmlDocGetRootElement(my_doc);//获取根节点
    xmlNodePtr my_child_node = my_root_node->children;//获取子节点
    while (my_child_node != NULL) 
    {
        if(my_child_node->type == XML_ELEMENT_NODE)
        {
            if(!strcmp(my_child_node->name, "deviceName"))
            {
                deviceInforTemp->deviceName = xmlNodeGetContent(my_child_node);
            }
            else if(!strcmp(my_child_node->name,"deviceID"))
            {
                deviceInforTemp->deviceID = xmlNodeGetContent(my_child_node);
            }
            else if(!strcmp(my_child_node->name, "serialNumber"))
            {
                deviceInforTemp->serialNumber = xmlNodeGetContent(my_child_node);
            }
            else if(!strcmp(my_child_node->name, "macAddress"))
            {
                deviceInforTemp->macAddress = xmlNodeGetContent(my_child_node);
            }
        }
        my_child_node = my_child_node->next;
    }

    xmlFree(my_doc);
    return size * nmemb;
}

/* 摄像头写操作 */
static int _hikvisionWrite(void* writePar)
{
    char response;
    char arg[1024];
    pReqArgs args = (pReqArgs)writePar;
    CURL *my_curl;
    CURLcode res;
    
    my_curl = curl_easy_init();
    curl_easy_setopt(my_curl, CURLOPT_CUSTOMREQUEST,"PUT");

    /* 判断Put类型 */
    switch (args->type)
    {
        case Time:
        {
            pTimeSelfPut timeTemp = (pTimeSelfPut)(args->selfPut);
            sprintf(arg,gTimeXmlResource,timeTemp->time);
            curl_easy_setopt(my_curl,CURLOPT_WRITEFUNCTION,writeTimeData);//接收数据并返回，常用来保存数据
            curl_easy_setopt(my_curl,CURLOPT_WRITEDATA,&response);
            break;
        }
        case OSD:
        {
            /* 读取设置参数 */
            pOSDSelfPut OSDTemp = (pOSDSelfPut)(args->selfPut);
            sprintf(arg,gOsdXmlResource,OSDTemp->name);
            curl_easy_setopt(my_curl,CURLOPT_WRITEFUNCTION,writeOSDData);//接收数据并返回，常用来保存数据
            curl_easy_setopt(my_curl,CURLOPT_WRITEDATA,&response);
            break;
        }
        default:
        {
            return -1;
        }
    }
    curl_easy_setopt(my_curl, CURLOPT_POSTFIELDS,(char*)arg); //请求的文件

    curl_easy_setopt(my_curl, CURLOPT_POSTFIELDSIZE, strlen(arg));
    
    curl_easy_setopt(my_curl, CURLOPT_URL, args->url);
    
    curl_easy_setopt(my_curl, CURLOPT_USERPWD, "admin:Rhky1234");
    
    curl_easy_setopt(my_curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

    curl_easy_setopt(my_curl,CURLOPT_TIMEOUT,5);

    curl_easy_setopt(my_curl,CURLOPT_MAXREDIRS,1);

    curl_easy_setopt(my_curl,CURLOPT_CONNECTTIMEOUT,5);

    res = curl_easy_perform(my_curl);

    curl_easy_cleanup(my_curl);

    return res;
}

/* 摄像头读操作 */
static int _hikvisionRead(void* readPar)
{
    printf("_hikvisionRead start.\r\n");
    char response;
    pReqArgs args = (pReqArgs)readPar;
    CURL *my_curl;
    CURLcode res;
    my_curl = curl_easy_init();
    curl_easy_setopt(my_curl, CURLOPT_CUSTOMREQUEST,"GET");
    
    curl_easy_setopt(my_curl, CURLOPT_URL, args->url);
    
    curl_easy_setopt(my_curl, CURLOPT_USERPWD, "admin:Rhky1234");
    
    curl_easy_setopt(my_curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

    switch (args->type)
    {
    case Time:
        curl_easy_setopt(my_curl,CURLOPT_WRITEFUNCTION,ReadTimeData);//接收数据并返回，常用来保存数据
    break;
    case Infor:
        curl_easy_setopt(my_curl,CURLOPT_WRITEFUNCTION,ReadInforData);//接收数据并返回，常用来保存数据
    break;
    default:
        break;
    }



    curl_easy_setopt(my_curl,CURLOPT_WRITEDATA,args->getInfo);

    curl_easy_setopt(my_curl,CURLOPT_TIMEOUT,5);

    curl_easy_setopt(my_curl,CURLOPT_MAXREDIRS,1);

    curl_easy_setopt(my_curl,CURLOPT_CONNECTTIMEOUT,5);

    res = curl_easy_perform(my_curl);

    if(0 == res)
    {
        printf("CURLE OK.\r\n");
    }
    printf("res = %d.\r\n",res);
    curl_easy_cleanup(my_curl);

}
    
/* 摄像头初始化操作 */
static int _hikvisionInit(void)
{
    printf("_hikvisionInit Init.\r\n");
    return 0;
}

/* 操作函数 */
static cameraOpt hikvisionOpt = 
{
    .init = _hikvisionInit,
    .read = _hikvisionRead,
    .write = _hikvisionWrite,
};

/* 初始化 */
int hikvisionInit(void)
{
    printf("hikvisionInit start.\r\n");
    hikvisionCamera.name = "HIKVISION";
    hikvisionCamera.cameraObjOpt = &hikvisionOpt;
    
    /* 注册设备 */
    cameraRegister(&hikvisionCamera);
    return 0;
}











